#include "m01_dis_task.h"
#include "cbb_bit.h"
#include "cbb_event.h"
#include "cbb_init.h"

#include "FreeRTOS.h"
#include "device.h"
#include "task.h"

#include "dev_uart.h"

#include "dev_output.h"
#include "myboard.h"

#include "cbb_verify_add8.h"
#include "cbb_ph_m01_dis.h"

#include "lvgl_mainwindow.h"

#include <stdio.h>

// M01 协议句柄
static PH_t* ph_m01_dis;

// 距离值
static uint32_t u32Dis;

/**
 * @brief 开始获取距离
 */
static void 
start_get_distance(void* pvArgs) {

    (void) pvArgs;

    u32Dis = 0;

    // 关闭蜂鸣器
    device_ioctl(dev_beep, OUTPUT_CMD_INACTIVE, NULL);


    // 发送缓存
    static uint8_t u8TxData[12];
    PH_Buf_t stTxBuf = {
        .pu8Buffer = u8TxData,
        .u32BufferLen = sizeof(u8TxData),
        .u32DataLen = 0,
    };

    // 设置要发送的参数
    M01_Dis_Data_t stM01DisData = {
        .u8Addr = 0,
        .u16Func = M01_DIS_READ_ONCE,
    };
    cbb_m01_dis_set_data(ph_m01_dis, &stM01DisData);

    // 构建数据包
    cbb_m01_dis_build(ph_m01_dis, &stTxBuf);

    // 发送数据包
    Dev_Uart_Data_t stData = {
        .pu8Data = u8TxData,
        .u32Len = sizeof(u8TxData),
    };
    device_ioctl(dev_usart3, UART_CMD_TRANSMIT, &stData);
}

/**
 * @brief 解析距离
 */
static void 
parse_distance(void* pvArgs) {

    (void) pvArgs;

    // 获取接收到的数据
    static uint8_t u8RxData[16];
    
    Dev_Uart_Data_t stData = {
        .pu8Data = u8RxData,
        .u32Len = sizeof(u8RxData),
    };
    device_ioctl(dev_usart3, UART_CMD_RECEIVE, &stData);

    PH_Buf_t stRxBuf = {
        .pu8Buffer = u8RxData,
        .u32BufferLen = sizeof(u8RxData),
        .u32DataLen = stData.u32Len,
    };

    // 解析数据包
    if(PH_OK == cbb_m01_dis_parse(ph_m01_dis, &stRxBuf)){
        // 获取距离数据
        M01_Dis_Data_t stM01DisData;
        cbb_m01_dis_get_data(ph_m01_dis, &stM01DisData);

        // 解析距离值
        u32Dis = stM01DisData.u32Data;

        // 获取完成后点亮蜂鸣器
        device_ioctl(dev_beep, OUTPUT_CMD_ACTIVE, NULL);

        printf("Dis: %d\n", u32Dis);
    };

    // 距离获取完成事件通知
    cbb_set_bit(&u32TaskID, EVENT_32, TASK_GET_DIS_SUCCESS);

}

/**
 * @brief 测距任务运行
 */
static void 
m01_dis_task_run(void *pvArgs){
    (void) pvArgs;

    for(;;)
    {

        // 监控usart3
        device_ioctl(dev_usart3,UART_CMD_MONITOR,NULL);

        // 监控事件
        cbb_event_monitor(event_usart3_rx);
        cbb_event_monitor(event_get_dis_task);

        // 任务延时
        vTaskDelay(pdMS_TO_TICKS(10));

    }
}

void m01_dis_task_init(void){

    // 协议句柄初始化
    PH_M01_Dis_t stPhM01Dis;
    ph_m01_dis = cbb_m01_dis_register(&stPhM01Dis, 
        cbb_verify_add8_check, 
        cbb_verify_add8_append);

    // 任务初始化
    static StaticTask_t stTaskTCB;
    static StackType_t  stTaskStack[configMINIMAL_STACK_SIZE * 10];
    static TaskHandle_t stTaskHandle = NULL;
    (void) stTaskHandle;

    stTaskHandle = xTaskCreateStatic(
        m01_dis_task_run,                   /* 任务函数 */
        "M01DisTask",                          /* 名字 */
        configMINIMAL_STACK_SIZE * 10,      /* 栈深度（字） */
        NULL,                           /* 参数 */
        tskIDLE_PRIORITY + 2,               /* 优先级 */
        stTaskStack,                   /* 静态栈数组 */
        &stTaskTCB);                 /* 静态 TCB 变量 */

    // 事件连接
    cbb_event_connect(event_btn1, start_get_distance, NULL);
    cbb_event_connect(event_usart3_rx, parse_distance, NULL);
    cbb_event_connect(event_get_dis_task, lvgl_show_dis, &u32Dis);
}
INIT_PORT_TASK(m01_dis_task_init);
